﻿Imports System.Activities
Imports System.Management
Imports System.Activities.Presentation.Metadata
Imports System.ComponentModel
Imports System.Drawing
Imports System.Activities.Presentation

Public MustInherit Class WMIExecuteActivityBase
    Inherits AsyncCodeActivity
    Implements IRegisterMetadata

    Protected _target As String = ""
    Protected _where As String = ""
    Protected _service As String = ""

    Public Property Scope As InArgument(Of ManagementScope)
    Public Property Results As OutArgument(Of List(Of Hashtable))

    Protected Delegate Function asyncExecuteWMIDelegate(ByVal target As String, ByVal whereCondition As String, ByVal wmScope As ManagementScope) As List(Of Hashtable)

    Protected Overrides Function BeginExecute(context As System.Activities.AsyncCodeActivityContext, callback As System.AsyncCallback, state As Object) As System.IAsyncResult
        Dim currentScope = context.GetValue(Me.Scope)

        Dim asyncExecute = New asyncExecuteWMIDelegate(AddressOf ExecuteWMI)
        context.UserState = asyncExecute

        Return asyncExecute.BeginInvoke(_target, _where, currentScope, callback, state)
    End Function

    Protected Overrides Sub EndExecute(context As System.Activities.AsyncCodeActivityContext, result As System.IAsyncResult)
        Dim asyncExecute = TryCast(context.UserState, asyncExecuteWMIDelegate)
        Dim wmiResult = asyncExecute.EndInvoke(result)

        context.SetValue(Me.Results, wmiResult)
    End Sub

    Protected Overridable Function ExecuteWMI(ByVal target As String, ByVal whereCondition As String, ByVal wmScope As ManagementScope) As List(Of Hashtable)
        Dim result As New List(Of Hashtable)
        Try
            wmScope = CreateScope(wmScope)

            Dim wmQueryString = "SELECT * FROM " + target
            If whereCondition.Trim <> "" Then wmQueryString += " WHERE " + whereCondition

            Dim wmQuery As New ObjectQuery(wmQueryString)

            Using searcher As New ManagementObjectSearcher(wmScope, wmQuery)
                Using queryCollection = searcher.Get()
                    For Each wmResult In queryCollection
                        Dim resultRecord As New Hashtable
                        For Each wmResultColumn In wmResult.Properties
                            resultRecord.Add(wmResultColumn.Name,
                                                    wmResultColumn.Value)
                        Next

                        If resultRecord.Count > 0 Then result.Add(resultRecord)
                    Next
                End Using
            End Using

        Catch ex As Exception
            Console.WriteLine("Exception :" + ex.Message)
            result.Clear()
        End Try
        Return result
    End Function

    Protected Overridable Function CreateScope(ByVal wmScope As ManagementScope) As ManagementScope
        If wmScope Is Nothing Then
            wmScope = New ManagementScope("\\" + My.Computer.Name + "\root\" + _service)
        End If
        If Not wmScope.IsConnected Then wmScope.Connect()
        Return wmScope
    End Function

    Public Overridable Sub Register() Implements System.Activities.Presentation.Metadata.IRegisterMetadata.Register
        Dim build As New AttributeTableBuilder
        'WMIExecuteActivityBase Activity
        build.AddCustomAttributes(GetType(WMIExecuteActivityBase),
                                              New DesignerAttribute(GetType(WMIDefaultActivityDesigner), GetType(ActivityDesigner)),
                                              New ToolboxBitmapAttribute(GetType(WMIExecuteActivityBase), "WmiDefault.png"))

        build.AddCustomAttributes(GetType(WMIExecuteActivityBase), "DisplayName",
                                      New CategoryAttribute(My.Resources.CategorySetting),
                                      New DisplayNameAttribute(My.Resources.DisplayNameDisplay))

        build.AddCustomAttributes(GetType(WMIExecuteActivityBase), "Scope",
                                      New CategoryAttribute(My.Resources.CategoryDetail),
                                      New DisplayNameAttribute(My.Resources.ScopeDisplay),
                                      New DescriptionAttribute(My.Resources.ScopeDescription))
        build.AddCustomAttributes(GetType(WMIExecuteActivityBase), "Results",
                                      New CategoryAttribute(My.Resources.CategoryDetail),
                                      New DisplayNameAttribute(My.Resources.ResultsDisplay),
                                      New DescriptionAttribute(My.Resources.ResultsDescription))

        MetadataStore.AddAttributeTable(build.CreateTable)
    End Sub
End Class
